package com.fruit.service.fruit;

import com.fruit.bean.constant.factory.PageFactory;
import com.fruit.bean.dto.fruit.FruitStockInfoDto;
import com.fruit.bean.entity.fruit.FruitStockInfo;
import com.fruit.bean.entity.fruit.FruitTypeInfo;
import com.fruit.bean.entity.system.User;
import com.fruit.bean.vo.front.Rets;
import com.fruit.bean.vo.query.DynamicSpecifications;
import com.fruit.dao.fruit.FruitStockRepository;
import com.fruit.dao.fruit.FruitTypeRepository;
import com.fruit.dao.system.UserRepository;
import com.fruit.service.BaseService;
import com.fruit.utils.BigDecimalUtils;
import com.fruit.utils.ContractTemplateUtils;
import com.fruit.utils.factory.Page;
import lombok.Data;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class FruitStockService extends BaseService<FruitStockInfo,Long, FruitStockRepository> {

    @Autowired
    private FruitStockRepository stockRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private FruitTypeRepository typeRepository;

    public Page<FruitStockInfoDto> queryStockPage() {
        Page<FruitStockInfo> page = new PageFactory().defaultPage();
        Page<FruitStockInfoDto> pageRes = new PageFactory().defaultPage();
        Pageable pageable;
        if (page.getSort() != null) {
            pageable = PageRequest.of(page.getCurrent() - 1, page.getSize(), page.getSort());
        } else {
            pageable = PageRequest.of(page.getCurrent() - 1, page.getSize(), Sort.Direction.DESC, "id");
        }
        Specification<FruitStockInfo> specification = DynamicSpecifications.bySearchFilter(
                page.getFilters(), stockRepository.getDataClass());
        org.springframework.data.domain.Page<FruitStockInfo> pageResult = stockRepository.findAll(specification, pageable);
        List<FruitStockInfo> fruitStockInfoList = pageResult.getContent();
        List<FruitStockInfoDto> fruitStockInfoDtoList = new ArrayList<>();
        for(FruitStockInfo fruitStockInfo : fruitStockInfoList){
            FruitStockInfoDto fruitStockInfoDto = new FruitStockInfoDto();
            fruitStockInfoDto.setFruitStockId(fruitStockInfo.getId());
            String fruitTypeName = typeRepository.getOne(fruitStockInfo.getFruitTypeId()).getFruitTypeName();
            fruitStockInfoDto.setFruitName(fruitTypeName);
            Optional<User> user = userRepository.findById(fruitStockInfo.getUserId());
            fruitStockInfoDto.setUserName(user.get().getAccount());
            fruitStockInfoDto.setFruitNumber(fruitStockInfo.getFruitStockNumber());
            fruitStockInfoDto.setStockStatus(fruitStockInfo.getFruitStockStatus());
            fruitStockInfoDto.setFruitDeficit(fruitStockInfo.getFruitStockDeficit());
            fruitStockInfoDto.setFruitInitNumber(fruitStockInfo.getFruitStockInitNumber());
            fruitStockInfoDtoList.add(fruitStockInfoDto);
        }
        pageRes.setTotal(Integer.valueOf(pageResult.getTotalElements() + ""));
        pageRes.setRecords(fruitStockInfoDtoList);
        return pageRes;
    }

    public List<FruitStockInfoDto> listStockInfo(Long userId){
        List<FruitStockInfoDto> stockInfoDtoList = new ArrayList<>();
        List<FruitStockInfo> stockInfoList = stockRepository.listStockInfo(userId);
        for(FruitStockInfo stockInfo : stockInfoList){
            if(stockInfo.getFruitStockNumber() == 0){
                continue;
            }
            FruitStockInfoDto fruitStockInfoDto = new FruitStockInfoDto();
            fruitStockInfoDto.setFruitName(typeRepository.getOne(stockInfo.getFruitTypeId()).getFruitTypeName());
            fruitStockInfoDto.setFruitStockId(stockInfo.getId());
            fruitStockInfoDto.setFruitNumber(stockInfo.getFruitStockNumber());
            fruitStockInfoDto.setStockStatus(stockInfo.getFruitStockStatus());
            stockInfoDtoList.add(fruitStockInfoDto);
        }
        return stockInfoDtoList;
    }




    /**
     * 获取合同模版
     * @param stockId
     * @return
     */
    public String getContract(Long stockId){
        FruitStockInfo fruitStockInfo = this.get(stockId);

        //获取库存水果名称和水果重量
        FruitTypeInfo typeInfo = typeRepository.getOne(fruitStockInfo.getFruitTypeId());
        User user = userRepository.getOne(fruitStockInfo.getUserId());
        return ContractTemplateUtils.getContract(String.valueOf(fruitStockInfo.getFruitStockNumber()),typeInfo.getFruitTypeName(),user.getAccount());
    }

    /**
     * 首页显示柱状图
     * @return
     */
    public Object listDashboardStockInfo(){
        List<FruitStockEChatsData> resList = new ArrayList<>();
        Map<String,Double> stockInfo = new HashedMap();
        List<FruitStockInfo> stockInfoList = this.queryAll();
        for(FruitStockInfo fruitStockInfo: stockInfoList){
            if(fruitStockInfo.getFruitStockStatus() != 2){
                // 已拒绝入库和还未入库的库存，不在首页柱状图展示
                continue;
            }
            String fruitName = typeRepository.getOne(fruitStockInfo.getFruitTypeId()).getFruitTypeName();
            if(stockInfo.containsKey(fruitName)){
                stockInfo.put(fruitName, BigDecimalUtils.add(stockInfo.get(fruitName),
                        fruitStockInfo.getFruitStockNumber()).doubleValue());
            }else{
                stockInfo.put(fruitName,fruitStockInfo.getFruitStockNumber());
            }
        }

        Set set = stockInfo.entrySet();
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            Map.Entry mapentry =(Map.Entry) iterator.next();
            FruitStockEChatsData fruitStockEChatsData = new FruitStockEChatsData();
            fruitStockEChatsData.setName(String.valueOf(mapentry.getKey()));
            fruitStockEChatsData.setNumber(Double.valueOf(mapentry.getValue().toString()));
            resList.add(fruitStockEChatsData);
        }
        return resList;
    }
}

@Data
class FruitStockEChatsData{
    String name;

    Double number;
}